package sunyu.kit.database;

import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.DataDictionaryGenerator;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import org.nutz.dao.Dao;
import org.slf4j.Logger;
import sunyu.kit.common.ExceptionKit;
import sunyu.kit.common.LogKit;

import javax.sql.DataSource;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 数据库工具类
 *
 * @author 孙宇
 */
public class DataBaseKit {

    private static final Logger logger = LogKit.getLogger();

    private static final Map<String, NutzDao> daoPool = new ConcurrentHashMap<>();//需要适应多个数据库

    /**
     * 添加dao用于操作数据库
     *
     * @param databaseName 数据库名称
     * @param dataSource   数据源
     */
    public static void addDao(String databaseName,
                              DataSource dataSource) {
        logger.info("初始化Nutz Dao {} 开始", databaseName);

        try {
            DatabaseMetaData metaData = dataSource.getConnection().getMetaData();

            for (Map.Entry<String, NutzDao> entry : daoPool.entrySet()) {
                NutzDao nutzDao = entry.getValue();
                DatabaseMetaData daoMetaData = nutzDao.getMetaData();
                if (metaData.getURL().equals(daoMetaData.getURL()) && metaData.getUserName().equals(daoMetaData.getUserName())) {
                    daoPool.put(databaseName, nutzDao);
                    logger.info("初始化Nutz Dao {} 结束", databaseName);
                    return;
                }
            }

            if (daoPool.containsKey(databaseName)) {
                logger.error("Nutz Dao {} 已存在!", databaseName);
                logger.info("初始化Nutz Dao {} 结束", databaseName);
                return;
            }

            logger.info("URL： {}", metaData.getURL());
            logger.info("userName： {}", metaData.getUserName());

            NutzDao dao = new NutzDao(dataSource);
            dao.setRunner(new SpringDaoRunner());
            daoPool.put(databaseName, dao);

            logger.info("初始化Nutz Dao {} 结束", databaseName);
        } catch (SQLException e) {
            logger.info("初始化Nutz Dao {} 失败", databaseName);
            logger.error(ExceptionKit.getStackTrace(e));
        }
    }

    /**
     * 获得Dao
     *
     * @param databaseName 数据库名称
     * @return
     */
    public static Dao getDao(String databaseName) {
        return daoPool.get(databaseName);
    }


    /**
     * 生成数据库字典
     *
     * @param dataSource 数据源
     * @param outputPath 输出目录
     * @param fileName   数据文件名
     */
    public static void generatorDatabaseMetaData(DataSource dataSource, String outputPath,
                                                 String fileName) {
        logger.info("准备生成TableMeta");
        MetaBuilder metaBuilder = new MetaBuilder(dataSource);
        metaBuilder.setDialect(new MysqlDialect());
        List<TableMeta> tableMetas = metaBuilder.build();
        if (tableMetas.size() == 0) {
            logger.info("TableMeta 数量为 0，不生成任何文件");
        } else {
            logger.info("TableMeta 数量为 {}", tableMetas.size());
            DataDictionaryGenerator dataDictionaryGenerator = new DataDictionaryGenerator(dataSource, outputPath);
            dataDictionaryGenerator.setDataDictionaryFileName(fileName);
            dataDictionaryGenerator.generate(tableMetas);
            logger.info("TableMeta生成完毕");
        }
    }

}
